/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hoja5;

/**
 *
 * @author luisorozco
 */

import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.ArrayList;
public class Hoja5 {
  
  double tiempoLlegadasMedio;
  double tiempoServicioMedio;
  static int totalClientes;
  //para probar con Lista Circulares
  //CircularQueue<Servidor> servidoresLibres;
  //CircularQueue<Cliente> colaClientes;
  
  //Probamos con arreglos
  ColaArreglo<Servidor> servidoresLibres;
  ColaArreglo<Cliente> colaClientes;
  Queue<Event> colaEventos;
  Random random = new Random();

  public Hoja5(int numServidores, double ptiempoLlegadasMedio)
  {
        tiempoServicioMedio = random.nextDouble()*30;
        tiempoLlegadasMedio = ptiempoLlegadasMedio;
        servidoresLibres = new ColaArreglo<Servidor>();
       // servidoresLibres = new CircularQueue<Servidor>()
        ;
        for (int j = 0; j < numServidores; j++){   
        //revisar
        servidoresLibres.insert(new Servidor(j));
        //servidoresLibres.add(new Servidor(j));
        }
    
    
    colaClientes = new ColaArreglo<Cliente>();
    //colaClientes = new ColaLista<Cliente>();
    totalClientes = 0;
    colaEventos = new java.util.PriorityQueue<Event>();
    siguienteLlegada(0.0); // schedule first client
  }

  public void siguienteLlegada(double tiempo)
  {
    double next = tiempo + 2 * tiempoLlegadasMedio * random.nextDouble();
    colaEventos.add(new Event(next));
  }
  
  

  /*
   * Los eventos que estan sucediendo en el bbanco
   */
  public double nextEvent()
  {
    Event ev = colaEventos.remove();
    System.out.println("Tiempo " + ev.darTiempo() + ": ");
//    System.out.println("Número de clientes en el banco: " + totalClientes);
    if (ev.darTipo() == Event.CLIENT_ARRIVES) {
       // schedule next client
      siguienteLlegada(ev.darTiempo());
      Cliente cliente = new Cliente(++totalClientes, ev.darTiempo(),
                                    random, tiempoServicioMedio);
      colaClientes.insert(cliente);
    } 
    // Event.SERVICE_FINISHED
    else {       
      Servidor servidor = ev.darServidor();
      servidor.finalizarServicio(ev.darTiempo());
      /*
       * servidoresLibres.add(servidor);
       */
      servidoresLibres.insert(servidor);
    }
    if (!servidoresLibres.isEmpty() && !colaClientes.isEmpty()) {
        /*
      Servidor servidor = servidoresLibres.poll();
      servidor.iniciarServicio(colaClientes.poll(), ev.darTiempo());
         */
      Servidor servidor = servidoresLibres.remove();
      servidor.iniciarServicio(colaClientes.remove(), ev.darTiempo());
      colaEventos.add(new Event(servidor.darCliente().darTiempoFinal(), servidor));
        }
    return ev.darTiempo();
  }
  
  
/*
   * Main del programa
   */
  public static void main(String [] args)
  {
        
        int numServidores = 4;
        double tiempoSimulacion = 480;
        double tiempoLlegadasMedio = 8; 
    System.out.println("Bienvenido a la Hoja 5");
    System.out.println("Simulacion de un Banco");
    System.out.println("");
    System.out.println("Número de servidores = " + numServidores); 
    System.out.println("Tiempo medio de llegada = " + tiempoLlegadasMedio); 

    Hoja5 sim = new Hoja5(numServidores, tiempoLlegadasMedio);

            double t;
            do {
              t = sim.nextEvent();
            } 
    
    //Aca se define los clientes que entran al banco
    while ((t < tiempoSimulacion) && (totalClientes<5));
  } 
}
